package com.friends.utils.excel.easyexcel3;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.enums.CellExtraTypeEnum;
import com.alibaba.excel.enums.WriteDirectionEnum;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.fill.FillConfig;
import com.friends.utils.ResponseUtil;
import com.friends.utils.excel.easyexcel3.handler.CustomCellWriteHandler;
import com.friends.utils.excel.easyexcel3.handler.ExcelMergeHandler;
import com.friends.utils.excel.easyexcel3.listener.ImportExcelListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * excel工具类
 */
@Slf4j
public class ExcelUtils3 {


    /**
     * easyExcel导入处理数据
     *
     * @param inputStream
     * @param clazz
     * @param sheetNo       处理sheetNo页数
     * @param headRowNumber 从第几行开始读取
     * @param <T>
     * @return
     */
    public static <T> List<T> importList(InputStream inputStream, Class<T> clazz, Integer sheetNo, Integer headRowNumber) {
        ImportExcelListener<T> listener = new ImportExcelListener<>(headRowNumber);
        try {
            EasyExcel.read(inputStream, clazz, listener).extraRead(CellExtraTypeEnum.MERGE).sheet(sheetNo).headRowNumber(headRowNumber).doRead();
        } catch (Exception e) {
            log.error("import.error.", e);
        }
        return listener.getData();
    }

    /**
     * easy-excel 模板竖向导出 (可参考 resources/templates/竖向导出模板.xlsx)
     *
     * @param list         数据
     * @param templateName 模板名称
     * @param tableName    导出名称
     * @param response
     * @ <T>
     */
    public static <T> void cellExport(List<T> list, String templateName, String tableName, HttpServletResponse response) {
        ExcelWriter excelWriter = null;
        try {
            response.setContentType("application/x-xls");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + URLEncoder.encode(tableName + ".xlsx", StandardCharsets.UTF_8.name()));
            InputStream template = new PathMatchingResourcePatternResolver().getResource("classpath:templates/" + templateName + ".xlsx").getInputStream();

            excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(template).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.VERTICAL).build();
            // 可填充头部活动信息
            Map<String, Object> activityInfoMap = new HashMap<>(16);
            activityInfoMap.put("time", "");
            activityInfoMap.put("branchName", "");

            excelWriter.fill(list, fillConfig, writeSheet);
            excelWriter.fill(activityInfoMap, writeSheet);
            excelWriter.finish();
//            excelWriter.close();
        } catch (IOException e) {
            log.error("cellExport.export.error." + tableName, e);
        } finally {
            if (excelWriter != null) {
//                excelWriter.close();
            }
        }
    }

    /**
     * easy-excel 模板横向导出 (可参考 resources/templates/横向导出模板.xlsx)
     *
     * @param list         数据
     * @param templateName 模板名称
     * @param tableName    导出名称
     * @param response
     * @ <T>
     */
    public static <T> void rowExport(java.util.List<T> list, String templateName, String tableName, HttpServletResponse response) {
        ExcelWriter excelWriter = null;
        try {
            response.setContentType("application/x-xls");
            response.setCharacterEncoding("UTF-8");
            response.setHeader("Content-Disposition", "attachment;filename*=UTF-8''" + URLEncoder.encode(tableName + ".xlsx", StandardCharsets.UTF_8.name()));
            InputStream template = new PathMatchingResourcePatternResolver().getResource("classpath:templates/" + templateName + ".xlsx").getInputStream();

            excelWriter = EasyExcel.write(response.getOutputStream()).withTemplate(template).build();
            WriteSheet writeSheet = EasyExcel.writerSheet().build();
            FillConfig fillConfig = FillConfig.builder().direction(WriteDirectionEnum.HORIZONTAL).build();
            // 可填充头部活动信息
            Map<String, Object> activityInfoMap = new HashMap<>(16);
            activityInfoMap.put("time", "");
            activityInfoMap.put("branchName", "");

            excelWriter.fill(list, fillConfig, writeSheet);
            excelWriter.fill(activityInfoMap, writeSheet);
            excelWriter.finish();
//            excelWriter.close();
        } catch (IOException e) {
            log.error("rowExport.export.error." + tableName, e);
        } finally {
            if (excelWriter != null) {
//                excelWriter.close();
            }
        }
    }

    /**
     * 暂未测试
     *
     * @param exportList
     * @param response
     */
    private static <T> void exportWaitExcel(List<T> exportList, HttpServletResponse response) {
        try {
            // 这里URLEncoder.encode可以防止中文乱码 当然和easyexcel没有关系
            String fileName = URLEncoder.encode("excelname", "UTF-8").replaceAll("\\+", "%20");
            response.setContentType("application/vnd.ms-excel;charset=UTF-8");
            response.setCharacterEncoding("UTF-8");
            /*请求头设置，Content-Disposition为下载标识，attachment标识以附件方式下载*/
            //response.addHeader("Content-Disposition", "attachment;filename=" + new String((title).getBytes(), "ISO8859-1") + ".xls");
            response.setHeader("Content-Disposition", "attachment;fileName=" + fileName + ".xls");
            response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
            // 这里需要设置不关闭流
            EasyExcel.write(response.getOutputStream())
                    .registerWriteHandler(new CustomCellWriteHandler())
                    .registerWriteHandler(new ExcelMergeHandler(1, new int[]{0, 1, 2, 3, 4, 7}))
                    .sheet("sheet页名称")
                    .doWrite(exportList);
        } catch (Exception e) {
            ResponseUtil.responseFailMessage(response, 500, "提示信息");
        }
    }

}
